﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;

namespace TSComm.Utilities.Datas
{
    /// <summary>
    /// DataTable,List关联的一些类
    /// DataTable和List相互转换通过反射来实现的.  
    /// 反射的效率似有点慢.但是可以接受.. 
    /// </summary>
    public static class DTExtension
    {
        /// <summary>
        /// DataTable 转换为List 集合
        /// </summary>
        /// <typeparam name="TResult">类型</typeparam>
        /// <param name="dt">DataTable</param>
        /// <returns></returns>
        public static List<TResult> ToList<TResult>(this DataTable dt) where TResult : class,new()
        {
            //创建一个属性的列表
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //获取TResult的类型实例  反射的入口
            Type t = typeof(TResult);
            //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表 
            Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });
            //创建返回的集合
            List<TResult> oblist = new List<TResult>();

            foreach (DataRow row in dt.Rows)
            {
                //创建TResult的实例
                TResult ob = new TResult();
                //找到对应的数据  并赋值
                prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
                //放入到返回的集合中.
                oblist.Add(ob);
            }
            return oblist;
        }

        /// <summary>
        /// 转换为一个DataTable
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<TResult>(this IEnumerable<TResult> value) where TResult : class
        {
            //创建属性的集合
            List<PropertyInfo> pList = new List<PropertyInfo>();
            //获得反射的入口
            Type type = typeof(TResult);
            DataTable dt = new DataTable();
            //把所有的public属性加入到集合 并添加DataTable的列
            Array.ForEach<PropertyInfo>(type.GetProperties(), p => { pList.Add(p); dt.Columns.Add(p.Name, p.PropertyType); });
            foreach (var item in value)
            {
                //创建一个DataRow实例
                DataRow row = dt.NewRow();
                //给row 赋值
                //p.GetValue(item, null)
                pList.ForEach(p => row[p.Name] = p.GetValue(item,null));
                //加入到DataTable
                dt.Rows.Add(row);
            }
            return dt;
        }


        ///// <summary>
        ///// 将泛型集合类转换成DataTable
        ///// </summary>
        ///// <typeparam name="T">集合项类型</typeparam>
        ///// <param name="list">集合</param>
        ///// <returns>数据集(表)</returns>
        //public static DataTable ToDataTable<T>(this IList<T> list)
        //{
        //    return ToDataTable<T>(list, null);
        //}

        ///// <summary>
        ///// 将泛型集合类转换成DataTable
        ///// </summary>
        ///// <typeparam name="T">集合项类型</typeparam>
        ///// <param name="list">集合</param>
        ///// <param name="propertyName">需要返回的列的列名</param>
        ///// <returns></returns>
        //public static DataTable ToDataTable<T>(this IList<T> list, params string[] propertyName)
        //{
        //    List<string> propertyNameList = new List<string>();
        //    if (propertyName != null)
        //        propertyNameList.AddRange(propertyName);

        //    DataTable result = new DataTable();
        //    if (list.Count > 0)
        //    {
        //        PropertyInfo[] propertys = list[0].GetType().GetProperties();
        //        foreach (PropertyInfo pi in propertys)
        //        {
        //            if (propertyNameList.Count == 0)
        //            {
        //                result.Columns.Add(pi.Name, pi.PropertyType);
        //            }
        //            else
        //            {
        //                if (propertyNameList.Contains(pi.Name))
        //                    result.Columns.Add(pi.Name, pi.PropertyType);
        //            }
        //        }

        //        for (int i = 0; i < list.Count; i++)
        //        {
        //            ArrayList tempList = new ArrayList();
        //            foreach (PropertyInfo pi in propertys)
        //            {
        //                if (propertyNameList.Count == 0)
        //                {
        //                    object obj = pi.GetValue(list[i], new Object[] { i });
        //                    tempList.Add(obj);
        //                }
        //                else
        //                {
        //                    if (propertyNameList.Contains(pi.Name))
        //                    {
        //                        object obj = pi.GetValue(list[i], new Object[] { 0 });
        //                        tempList.Add(obj);
        //                    }
        //                }
        //            }
        //            object[] array = tempList.ToArray();
        //            result.LoadDataRow(array, true);
        //        }
        //    }
        //    return result;
        //}
    }
}
